package org.hzz.coupon.infrastructure.repository.mybatis;

import io.gitee.pkmer.common.collection.CollUtil;
import io.gitee.pkmer.convention.converter.RecordAndEntityConverter;
import io.gitee.pkmer.convention.page.PageResponse;
import io.gitee.pkmer.convention.page.query.PageQuery;
import io.gitee.pkmer.convention.repository.nomapper.PageBaseRepository;
import lombok.Setter;
import org.hzz.coupon.infrastructure.dao.mapper.code.ExchangeCodeDynamicMapper;
import org.hzz.coupon.infrastructure.dao.mapper.code.ExchangeCodeMapper;
import org.hzz.coupon.infrastructure.dao.mapper.code.ExchangeCodePageQueryMapper;
import org.hzz.coupon.infrastructure.dao.model.code.ExchangeCode;
import org.hzz.promotions.domain.entity.ExchangeCodeEntity;
import org.hzz.promotions.domain.repository.ExchangeCodeRepository;
import org.hzz.promotions.types.constants.ExchangeCodeFields;
import org.hzz.promotions.types.enums.code.CodeType;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider;
import org.mybatis.dynamic.sql.insert.render.MultiRowInsertStatementProvider;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

import static org.hzz.coupon.infrastructure.dao.mapper.code.ExchangeCodeDynamicSqlSupport.*;
import static org.mybatis.dynamic.sql.SqlBuilder.*;

/**
 * @author <a href="mailto:1193094618@qq.com">pkmer</a>
 * <br>
 * <a href = "https://gitee.com/developeros/videos-online">Code Repository</a>
 * At 2024/8/31
 */
@Repository
public class ExchangeCodeRepositoryImpl
        extends PageBaseRepository<ExchangeCodePageQueryMapper, ExchangeCode>
        implements ExchangeCodeRepository {

    @Setter(onMethod_ = @Autowired)
    private ExchangeCodeDynamicMapper dynamicMapper;
    @Setter(onMethod_ = @Autowired)
    private ExchangeCodeMapper mapper;

    /**
     * {@inheritDoc}
     *
     * @param entity 兑换码实体
     */
    @Override
    public void insertExchangeCode(ExchangeCodeEntity entity) {
        ExchangeCode record = Converter.INSTANCE.toRecord(entity);
        mapper.insertSelective(record);
    }

    /**
     * {@inheritDoc}
     *
     * @param entities 兑换码实体列表
     */
    @Override
    public void batchInsertExchangeCodes(List<ExchangeCodeEntity> entities) {
        if (CollUtil.isEmpty(entities)) return;
        List<ExchangeCode> records = Converter.INSTANCE.toRecords(entities);

        MultiRowInsertStatementProvider<ExchangeCode> multiRowInsert = insertMultiple(records).into(exchangeCode)
                .map(id).toProperty(ExchangeCodeFields.ID)
                .map(code).toProperty("code")
                .map(type).toProperty("type")
                .map(exchangeTargetId).toProperty("exchangeTargetId")
                .map(expiredTime).toProperty("expiredTime")
                .build()
                .render(RenderingStrategies.MYBATIS3);

        System.out.println(multiRowInsert.getInsertStatement());
        dynamicMapper.insertMultiple(multiRowInsert);
    }

    /**
     * {@inheritDoc}
     *
     * @param targetId 目标id
     */
    @Override
    public void deleteCouponCodeByTargetId(Long targetId) {
        DeleteStatementProvider deleteStatement = deleteFrom(exchangeCode)
                .where(exchangeTargetId, isEqualTo(targetId))
                .build()
                .render(RenderingStrategies.MYBATIS3);
        logger.info(deleteStatement.getDeleteStatement());
        dynamicMapper.delete(deleteStatement);
    }

    /**
     * {@inheritDoc}
     *
     * @param serialNum 序列号
     * @param codeType 类型
     */
    @Override
    public Optional<ExchangeCodeEntity> selectBySerialNum(int serialNum, CodeType codeType) {
        Optional<ExchangeCode> record = dynamicMapper.selectOne(c ->
                c.where(id, isEqualTo(serialNum))
                        .and(type, isEqualTo(codeType)));

        return record.map(Converter.INSTANCE::toEntity);
    }

    @Override
    public PageResponse<ExchangeCodeEntity> pageQueryCode(PageQuery pageQuery) {
        PageResponse<ExchangeCode> exchangeCodePageResponse = super.pageQuery(pageQuery);
        return Converter.INSTANCE.convertToEntityPage(exchangeCodePageResponse);
    }

    @Override
    public void updateExchangeCode(ExchangeCodeEntity entity) {
        ExchangeCode record = Converter.INSTANCE.toRecord(entity);
        mapper.updateByPrimaryKeySelective(record);
    }


    @Mapper
    interface Converter extends RecordAndEntityConverter<ExchangeCode, ExchangeCodeEntity> {
        Converter INSTANCE = Mappers.getMapper(Converter.class);
    }
}
